﻿package net.wangit.jdbc.table;


import net.wangit.MapList;
import net.wangit.Row;
import net.wangit.jdbc.DB;
import net.wangit.jdbc.ServerAccessException;
import net.wangit.jdbc.util.DBHelper;
import net.wangit.util.Checker;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TableMetaFactory {
	private static final Log log = LogFactory.getLog(TableMetaFactory.class);
	private static final String SQL_TABLE = "select * from TABLE where t=?";
	private static final String SQL_COLUMN = "select * from COLUMN where t=? and v=1 order by o";

	public static synchronized TableMeta getTableMeta(String domain,
			String tableName) {
		if ((Checker.isEmpty(domain)) || (Checker.isEmpty(tableName))) {
			log.error("empty arguments is not acceptable: domain=" + domain
					+ " tableName=" + tableName);
			return null;
		}
		tableName = tableName.toUpperCase();
		TableMeta tableMeta = TableCache.get(domain, tableName);
		if (tableMeta == null) {
			tableMeta = createTableMeta(domain, tableName);
			TableCache.put(domain, tableName, tableMeta);
			log.debug("TableMeta created : " + domain + "/" + tableName);
		}
		return tableMeta;
	}

	private static TableMeta createTableMeta(String domain, String tableName) {
		DB db = DBHelper.getDomainDB(domain);
		MapList list;
		try {
			list = db.query(TableMetaFactory.SQL_TABLE, tableName, 2);
		} catch (Exception e) {
			log.error("could not query table in server: " + domain, e);
			throw new ServerAccessException("could not query table in server: "
					+ domain);
		}
		if (Checker.isEmpty(list)) {
			log.error("Table not found ：" + domain + "/" + tableName);
			throw new TableConfigurationException("Table not found ：" + domain
					+ "/" + tableName);
		}
		Row firstRow = list.getRow(0);
		TableMeta meta = new TableMeta(domain, tableName);
		String schema = firstRow.get("s");
		if (!(Checker.isEmpty(schema))) {
			meta.setSchema(schema);
		}
		String logTableName = firstRow.get("lt");
		if (!(Checker.isEmpty(logTableName))) {
			meta.setLogTableName(logTableName);
		}
		String versionColumnName = firstRow.get("vc");
		try {
			list = db.query(TableMetaFactory.SQL_COLUMN, tableName, 2);
		} catch (Exception e) {
			log.error("could not query column in server: " + domain, e);
			throw new ServerAccessException(
					"could not query column in server: " + domain);
		}
		if (Checker.isEmpty(list)) {
			log.error("table's columns not found ：" + domain + "/" + tableName);
			throw new TableConfigurationException("table's columns not found ："
					+ domain + "/" + tableName);
		}
		StringBuffer columnsString = new StringBuffer();
		for (int i = 0; i < list.size(); ++i) {
			Row row = list.getRow(i);
			int isPrimaryKeyColumn = row.getInt("pk", 0);
			Column column = ColumnFactory.getColumn(domain, row);
			meta.addColumn(column);
			columnsString.append(column.getName()).append(",");
			if (isPrimaryKeyColumn == 1) {
				meta.addPrimaryKeyColumn(column);
			}
			if (column.getName().equals(versionColumnName)) {
				meta.setVersionColumn(column);
			}
		}
		if (meta.getPrimaryKey().getColumns().size() == 0) {
			throw new TableConfigurationException(
					"the table has no primarykey :" + domain + "/" + tableName);
		}
		meta.setColumnsString(columnsString.toString());
		return meta;
	}
}